// File Name: flash_ctrl.c
// Author: kukukukuku~
// Date: 2024-07-12

#include "./User/Flash/inc/flash_ctrl.h"

uint16_t flashData[FLASH_DATA_NUM]; //Flash数据

uint8_t flashSaveFlag;  //Flash保存结果标志
uint8_t flashReadFlag;  //Flash读取结果标志

uint8_t versionMain;    //主版本号
uint8_t versionSecond;  //次版本号
uint8_t versionPhase;   //阶段版本号

/**
 * @brief   擦除扇区
 * @param   flashSectorsAddrStart:  扇区起始地址
 * @retval  擦除结果
 * - 0:     擦除成功
 * - 1:     等待超时
 * - 2:     擦除失败
 * - 3:     扇区起始地址错误
 * @note    None
*/
uint8_t flash_erase_sectors(const uint32_t flashSectorsAddrStart)
{
    flash_status_type flashStatus = FLASH_OPERATE_DONE;
    
    //扇区起始地址地址正确
    if(flashSectorsAddrStart % FLASH_SECTORS_SIZE == 0)
    {
        flashStatus = flash_operation_wait_for(ERASE_TIMEOUT);
        if(flashStatus == FLASH_PROGRAM_ERROR || flashStatus == FLASH_EPP_ERROR)
        {
            flash_flag_clear(FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
        }
        else if(flashStatus == FLASH_OPERATE_TIMEOUT)
        {
            return 1;   //等待超时
        }
        flashStatus = flash_sector_erase(flashSectorsAddrStart);
        if(flashStatus != FLASH_OPERATE_DONE)
        {
            return 2;   //擦除失败
        }
        
        return 0;
    }
    
    return 3;   //扇区起始地址地址错误
}


/**
 * @brief   写入字节数据
 * @param   flashAddr:  要写入的起始地址
 * @param   data:       要写入的数据
 * @retval  写入结果
 * - 0:     写入成功
 * - 1:     地址不在扇区范围内
 * @note    None
*/
uint8_t flash_program_data_byte(const uint32_t flashAddr, uint8_t data)
{
    if(flashAddr >= FLASH_ADDR_DATA_START && flashAddr <= FLASH_ADDR_DATA_STOP)
    {
        flash_byte_program(flashAddr, data);
        return 0;
    }
    
    return 1;   //地址不在扇区范围内
}


/**
 * @brief   写入半字数据
 * @param   flashAddr:  要写入的起始地址
 * @param   data:       要写入的数据
 * @retval  写入结果
 * - 0:     写入成功
 * - 1:     地址不在扇区范围内
 * @note    None
*/
uint8_t flash_program_data_halfword(const uint32_t flashAddr, uint16_t data)
{
    if(flashAddr >= FLASH_ADDR_DATA_START && flashAddr <= FLASH_ADDR_DATA_STOP - 1)
    {
        flash_halfword_program(flashAddr, data);
        return 0;
    }
    
    return 1;   //地址不在扇区范围内
}


/**
 * @brief   写入字数据
 * @param   flashAddr:  要写入的起始地址
 * @param   data:       要写入的数据
 * @retval  写入结果
 * - 0:     写入成功
 * - 1:     地址不在扇区范围内
 * @note    None
*/
uint8_t flash_program_data_word(const uint32_t flashAddr, uint32_t data)
{
    if(flashAddr >= FLASH_ADDR_DATA_START && flashAddr <= FLASH_ADDR_DATA_STOP - 3)
    {
        flash_word_program(flashAddr, data);
        return 0;
    }
    
    return 1;   //地址不在扇区范围内
}
